package com.pp.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pp.common.pojo.User;
import com.pp.common.util.JwtUtils;
import com.pp.common.util.MD5Utils;
import com.pp.web.mapper.UserMapper;
import com.pp.web.model.dto.LoginDTO;
import com.pp.web.model.dto.RegisterDTO;
import com.pp.web.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public User register(RegisterDTO registerDTO) throws UsernameDuplicateException {
        // 查询是否有相同 username 的用户
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // username
        lambdaQueryWrapper.eq(User::getUsername, registerDTO.getUsername());
        User user = this.baseMapper.selectOne(lambdaQueryWrapper);

        // 若注册的 user 已存在
        if (!ObjectUtils.isEmpty(user)) {
            // 抛出自定义的 UsernameDuplicateException 用户名重复异常
            throw new UsernameDuplicateException("用户名已经被占用");
        }

        // 若为新用户，则创建 newUser 对象
        User newUser = User.builder()
                           .username(registerDTO.getUsername())
                           .nickname(registerDTO.getUsername())
                           .password(MD5Utils.encryptPassword(registerDTO.getPassword()))
                           .email(registerDTO.getEmail())
                           .createdUser(registerDTO.getUsername())
                           .updatedUser(registerDTO.getUsername())
                           .build();

        // 将 newUser 入库
        this.baseMapper.insert(newUser);

        // 返回 newUser 用于前端页面数据回显
        return newUser;
    }

    @Override
    public String login(LoginDTO loginDTO) throws PasswordMismatchException {
        // 获取从前端传过来的 username 和 password
        User user = this.getUserByUsername(loginDTO.getUsername());
        String encryptedPassword = MD5Utils.encryptPassword(loginDTO.getPassword());

        // 校验前端传递过来的 password 是否与数据库中的 password 一致
        if(!encryptedPassword.equals(user.getPassword()))
            throw new PasswordMismatchException("密码匹配错误");

        // 若校验密码成功，则返回根据 username 生成的 JWT
        return JwtUtils.generateToken(user.getUsername());
    }

    @Override
    public User getUserById(String id) {
        return userMapper.selectById(id);
    }

    @Override
    public User getUserByUsername(String username) {
        return this.baseMapper.selectOne(
            new LambdaQueryWrapper<User>().eq(User::getUsername, username)
        );
    }

    /**
     * 自定义 UsernameDuplicateException 用户名重复异常类
     */
    static class UsernameDuplicateException extends RuntimeException {
        public UsernameDuplicateException(String message) {
            super(message);
        }
    }

    /**
     * 自定义 PasswordMismatchException 密码匹配异常类
     */
    static class PasswordMismatchException extends RuntimeException {
        public PasswordMismatchException(String message) {
            super(message);
        }
    }

}
